/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Piezas;

import Interfaz.Display;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author Jorge
 */
public class Matriz {

    public Cuadrado[][] arrayPiezas; //0 = no hay trozo; 1 = Hay trozo ; 2 = pieza actual;
    public int cActual, fActual;
    public int fMatActual = 0, cMatActual = 1;//Matriz de 4/4
    public String imgActual;
    private Display game;

    public Matriz(Display game_) {
        arrayPiezas = new Cuadrado[18][10];
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                arrayPiezas[i][j] = new Cuadrado();
            }
        }
        this.game = game_;
    }

    public void renderMat(Graphics2D g2d) {
        int aumX = 0;
        int aumY = 0;
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[i][j].tipoCuadrado == 2 || arrayPiezas[i][j].tipoCuadrado == 1) {
                    arrayPiezas[i][j].renderCuadrado(g2d, aumX, aumY);
                }
                aumX += 27 + 3;
            }
            aumX = 0;
            aumY += 28 + 3;
        }
    }

    public void nuevaPieza(Pieza nuevaPieza, boolean sig) { //Mejorar el algoritmo de aleatoriedad
        //Condicion de Aleatoriedad
        //Traerse una pieza aleatoria de TipoPieza
        int[] pieza = null;
        int extrm = 7;
        Random rnd = new Random();
        int opc = rnd.nextInt(5);
        if (game.extremo) {
            extrm = 8;
        } else {
            extrm = 7;
        }
        if (nuevaPieza.tipo == -1) {
            nuevaPieza.tipo = rnd.nextInt(extrm);
            nuevaPieza.imagen = opc;
            this.imgActual = Integer.toString(opc);
        } else {
            this.imgActual = Integer.toString(nuevaPieza.imagen);
        }
        switch (nuevaPieza.tipo) {
            case 0:
                pieza = TipoPieza.pieza0; // L
                fActual = 1;
                cActual = 4;
                break;
            case 1:
                pieza = TipoPieza.pieza1; // O
                fActual = 0;
                cActual = 4;
                break;
            case 2:
                pieza = TipoPieza.pieza2; // Z
                fActual = 0;
                cActual = 4;
                break;
            case 3:
                pieza = TipoPieza.pieza3; // I
                fActual = 1;
                cActual = 4;
                break;
            case 4:
                pieza = TipoPieza.pieza4; // T
                fActual = 1;
                cActual = 4;
                break;
            case 5:
                pieza = TipoPieza.pieza5; // J
                fActual = 1;
                cActual = 4;
                break;
            case 6:
                pieza = TipoPieza.pieza6; // S
                fActual = 0;
                cActual = 4;
                break;
            case 7:
                pieza = TipoPieza.pieza7;
                fActual = 2;
                cActual = 4;
                break;
        }
        game.piezaActual = nuevaPieza;
        if (sig) {
            game.piezaSiguiente = new Pieza(rnd.nextInt(extrm), rnd.nextInt(5));
            game.matrizDatosSig.setPieza(game.piezaSiguiente);
        }
        System.out.println(game.piezaSiguiente.tipo);
        for (int i = 0; i < pieza.length; i = i + 2) { //Revisar esto!
            if (arrayPiezas[pieza[i]][pieza[i + 1]].tipoCuadrado == 1) {
                gameOver();
                i = 8;
            } else {
                arrayPiezas[pieza[i]][pieza[i + 1]].tipoCuadrado = 2;
                arrayPiezas[pieza[i]][pieza[i + 1]].setImagen(imgActual);
            }
        }
        //System.out.println("fila  " + fActual + "  columna  " + cActual);
    }

    public void setTipo(int tipo, Cuadrado[][] array) {
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (array[i][j].tipoCuadrado == 2) {
                    array[i][j].tipoCuadrado = tipo;
                }
            }
        }
    }

    public void actualizar() {
        int[][] aux = Utilidades.Utils.obtenerMatriz(arrayPiezas, 0);
        //Utilidades.Utils.printArrayCuadrados(arrayPiezas);
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[i][j].tipoCuadrado == 2) {
                    aux[i + 1][j] = 2;
                }
            }
        }
        arrayPiezas = Utilidades.Utils.devolverMatriz(aux, arrayPiezas, imgActual);
        this.fActual++;
    }

    public boolean colisionPiezas() {
        boolean colision = false;
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[i][j].tipoCuadrado == 2) {
                    if (arrayPiezas[i + 1][j].tipoCuadrado == 1) {
                        colision = true;
                        j = 10;
                        i = 18;
                    }
                }
            }
        }
        return colision;
    }

    public void desplazar(int direccion) {
        boolean colision = false;
        int[][] aux = Utilidades.Utils.obtenerMatriz(arrayPiezas, 0);
        //Utilidades.Utils.printArrayCuadrados(arrayPiezas);
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[i][j].tipoCuadrado == 2) {
                    if (arrayPiezas[i][j + direccion].tipoCuadrado == 1) {
                        colision = true;
                        j = 10;
                        i = 18;
                    } else {
                        aux[i][j + direccion] = 2;
                    }
                }
            }
        }
        if (!colision) {
            arrayPiezas = Utilidades.Utils.devolverMatriz(aux, arrayPiezas, imgActual);
            this.cActual += direccion;
        }
    }

    public boolean colisionDerecha() {
        boolean aux = false;
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[i][j].tipoCuadrado == 2) {
                    if (j == 9) {
                        return true;
                    }
                }
            }
        }
        return aux;
    }

    public boolean colisionIzquierda() {
        boolean aux = false;
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[i][j].tipoCuadrado == 2) {
                    if (j == 0) {
                        return true;
                    }
                }
            }
        }
        return aux;
    }

    public boolean colisionAbajo() {
        boolean aux = false;
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[i][j].tipoCuadrado == 2) {
                    if (i == 17) {
                        return true;
                    }
                }
            }
        }
        return aux;
    }

    public void rotarPieza() {
        //Copiar matriz de enteros
        //Obtener posicion del cuadrado principal
        //Trasladar al 0,0 rotar desde el 0,0
        //Trasladar a la posicion del cuadrado
        //Comprobar si alguna de los cuadrados se pasa de rango o si ha chocado con alguna pieza
        //Si se pasa dejamos como este, sino se pasa, seteamos la matriz original 
        //a la de enteros y sus imagenes
        boolean colision = false;
        int[][] aux = Utilidades.Utils.obtenerMatriz(arrayPiezas, 0);
        Point nuevoPunto = new Point();
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[i][j].tipoCuadrado == 2) {
                    nuevoPunto.x = i - fActual; //Traladado al 0
                    nuevoPunto.y = j - cActual;
                    int auxP = nuevoPunto.x;
                    nuevoPunto.x = nuevoPunto.y + fActual;
                    nuevoPunto.y = -auxP + cActual;
                    if (nuevoPunto.y >= 0 && nuevoPunto.y <= 9 && nuevoPunto.x >= 0
                            && nuevoPunto.x <= 17) {
                        if (arrayPiezas[nuevoPunto.x][nuevoPunto.y].tipoCuadrado != 1) {
                            aux[nuevoPunto.x][nuevoPunto.y] = 2;
                        } else {
                            colision = true;
                            i = 18;
                            j = 10;
                        }
                    } else {
                        colision = true;
                        i = 18;
                        j = 10;
                    }
                }
            }
        }
        if (!colision) {
            arrayPiezas = Utilidades.Utils.devolverMatriz(aux, arrayPiezas, imgActual);
        }
    }

    public void examinarLineas(ArrayList array) {
        //Recorrer lineas comprobando si son todo "unos"
        //Si lo son llamar a limpiar fila para que las setee a 0
        //Aumentar uno al contador aux de lineas
        //Por cada lineaAux quitada desplazar tanto imagen como los "unos"
        //sumar lineaAux al contador de lineas
        //Hacer lo correspondiente con los puntos
        ArrayList arrayFilas = new ArrayList();
        boolean filaLlena = true;
        for (int i = 0; i < array.size(); i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[(Integer) (array.get(i))][j].tipoCuadrado != 1) {
                    filaLlena = false;
                    j = 10;
                }
            }
            if (filaLlena) {
                Display.lineasTotales++;
                arrayFilas.add((Integer) (array.get(i)));
            }
            filaLlena = true;
        }
        if (!arrayFilas.isEmpty()) {
            Display.puntos += 5 * arrayFilas.size();
            borrarFilas(arrayFilas);
            desplazarUnos(arrayFilas);
        }
    }

    public void desplazarUnos(ArrayList filas) {
        //Realizar con matriz auxiliar de cuadrados
        //Seteamos todos los cuadrados a los que vienen de la original
        //Si es un uno, lo seteamos un fila bajada
        Cuadrado[][] aux = new Cuadrado[18][10];
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                aux[i][j] = new Cuadrado();
            }
        }
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (i < (Integer) filas.get(0)) {
                    aux[i + filas.size()][j].tipoCuadrado = arrayPiezas[i][j].tipoCuadrado;
                    aux[i + filas.size()][j].imagen = arrayPiezas[i][j].imagen;
                } else if (i > (Integer) filas.get(filas.size() - 1)) {
                    aux[i][j].tipoCuadrado = arrayPiezas[i][j].tipoCuadrado;
                    aux[i][j].imagen = arrayPiezas[i][j].imagen;
                }
            }
        }
        arrayPiezas = aux;
    }

    public void gameOver() {
        game.restart();
    }

    public ArrayList obtenerFilas() {
        ArrayList arrayAux = new ArrayList();
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (arrayPiezas[i][j].tipoCuadrado == 2) {
                    arrayAux.add(i);
                    j = 10;
                }
            }
        }
        return arrayAux;
    }

    private void borrarFilas(ArrayList array) {
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                if (array.contains(i)) {
                    arrayPiezas[i][j].tipoCuadrado = 0;
                }
            }
        }
    }

    public void reset() {
        for (int i = 0; i < 18; i++) {
            for (int j = 0; j < 10; j++) {
                arrayPiezas[i][j].tipoCuadrado = 0;
            }
        }
    }
}
